﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;

namespace Fine.CRM.Common
{
    internal enum CloneType {Create = 1, Update = 2};

    internal static class CloneRecordAttributes
    {
        //public static void CloneRecordFields(this IOrganizationService orgService, Entity sourceEntity, ref Entity targetEntity, CloneType cloneType, List<string> excludeFields)
        public static void CloneRecordFields(this Entity targetEntity, Entity sourceEntity, IOrganizationService orgService, CloneType cloneType, List<string> excludeFields)
    {
            if(excludeFields == null)
                excludeFields = new List<string>();
            
            //always excluded the entity id
            string entityIdField = sourceEntity.LogicalName + "id";
            if(!excludeFields.Contains(entityIdField))
            {
                excludeFields.Add(entityIdField);
            }

            //get the set of allowed fields based on the metadata for either a create or update
            //operation.
            List<string> allowedFields;
            if (cloneType == CloneType.Create)
                allowedFields = orgService.GetMetaDataCreateFieldNames(sourceEntity.LogicalName);
            else
                allowedFields = orgService.GetMetaDataUpdateFieldNames(sourceEntity.LogicalName);

            //loop through each allowed field and copy the attribute from the source to the target
            //if all of the following conditions are true:
            //  - attribute exists in the source and is not null
            //  - atribute is not on the exclusion list
            //  - attribute does not already exist in the target
            foreach (string fieldName in allowedFields)
            {
                if (sourceEntity.Contains(fieldName)
                    && sourceEntity[fieldName] != null
                    && !excludeFields.Contains(fieldName)
                    && !targetEntity.Contains(fieldName))
                {
                    object value = sourceEntity[fieldName];
                    targetEntity.AddUpdateAttribute(fieldName, value);
                }

            }
        }
    }
}
